<?php

namespace common\helpers;

use Yii;
use yii\helpers\BaseFileHelper;
use yii\imagine\Image;
use yii\base\InvalidConfigException;

/**
 * 文件相关扩展静态函数类
 *
 * @author emhome <emhome@163.com>
 * @since 1.0
 */
class FileHelper extends BaseFileHelper {

    /**
     * 判断远程文件是否存在（Curl方式）
     *
     * @param string $url 远程文件地址
     * @return boolean
     */
    public static function remoteFileExist($url) {
        $curl = curl_init($url);
        curl_setopt($curl, CURLOPT_NOBODY, true);
        $result = curl_exec($curl);
        if ($result === false) {
            return false;
        }
        $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        curl_close($curl);
        if ($statusCode !== 200) {
            return false;
        }
        return true;
    }

    /**
     * 转换目录下面的所有文件编码格式
     * 
     * @param	string	$in_charset		原字符集
     * @param	string	$out_charset	目标字符集
     * @param	string	$dir			目录地址
     * @param	string	$fileexts		转换的文件格式
     * @return	string	如果原字符集和目标字符集相同则返回false，否则为true
     */
    public static function encodeFormat($in_charset, $out_charset, $dir, $fileexts = 'php|html|htm|shtml|shtm|js|txt|xml') {
        if ($in_charset == $out_charset) {
            return false;
        }
        $list = self::findFiles($dir);
        foreach ($list as $v) {
            if (pathinfo($v, PATHINFO_EXTENSION) == $fileexts && is_file($v)) {
                file_put_contents($v, iconv($in_charset, $out_charset, file_get_contents($v)));
            }
        }
        return true;
    }

    /**
     * 目录列表
     * 
     * @param	string	$dir		路径
     * @param	int		$parentid	父id
     * @param	array	$dirs		传入的目录
     * @return	array	返回目录列表
     */
    public static function dirTree($dir, $parentid = 0, $dirs = array()) {
        global $id;
        if ($parentid == 0) {
            $id = 0;
        }
        $list = glob($dir . '*');
        foreach ($list as $v) {
            if (is_dir($v)) {
                $id++;
                $dirs[$id] = array('id' => $id, 'parentid' => $parentid, 'name' => basename($v), 'dir' => $v . '/');
                $dirs = self::dirTree($v . '/', $id, $dirs);
            }
        }
        return $dirs;
    }

    /**
     * 生成上传文件的文件名
     *
     * @param string $ext 扩展名
     * @return string 返回文件名
     */
    public static function buildUploadFileName($ext = false) {
        $tempname = StringHelper::random(6) . md5(Yii::$app->user->id . time() . StringHelper::random(4));
        if ($ext !== false) {
            return $tempname . '.' . ltrim($ext, '.');
        }
        return $tempname;
    }

    /**
     * 保存远程图片
     *
     * @param string $ext 扩展名
     * @return string 返回文件名
     */
    public static function saveImageFromRemote($url, $path, $basePath, $filename = null, $ext = 'png') {
        $uploadPath = rtrim($basePath, '/') . '/' . ltrim($path, '/');
        static::createDirectory($uploadPath);
        if (!$filename) {
            $filename = static::buildUploadFileName($ext);
        }
        Image::frame($url, 0, '000', 0)->save($uploadPath . $filename);
        return $path . $filename;
    }

    /**
     * 生成分类顶部图片
     *
     * @param string $ext 扩展名
     * @return string 返回文件名
     */
    public static function spreadCover($color, $bgcolor, $photo, $title, $description) {
        $params = func_get_args();
        $filename = md5(implode('', $params)) . '.png';
        $path = '/attachments/category/' . date('Ym/d') . '/';
        $savepath = Yii::getAlias('@uploads') . $path;
        static::createDirectory($savepath);

        $rgb = StringHelper::hex2rgb($bgcolor);
        $rgbFont = StringHelper::hex2rgb($color);
        $font = Yii::getAlias('@common/data/fonts/msyh.ttf');

        $width = 140;
        $height = 140;

        //2.创建画布
        $img = imagecreatetruecolor(400, 160);
        //1.准备颜色
        $background = imagecolorallocate($img, $rgb[0], $rgb[1], $rgb[2]);
        $fontColor = imagecolorallocate($img, $rgbFont[0], $rgbFont[1], $rgbFont[2]);
        $fontColorAlpha = imagecolorclosestalpha($img, $rgbFont[0], $rgbFont[1], $rgbFont[2], 40);
        $trans_color = imagecolorallocatealpha($img, 0, 0, 0, 127);

        imagesavealpha($img, true);
        imagefill($img, 0, 0, $trans_color);

        //3.填充背景颜色
        imagefilledrectangle($img, 0, 35, 400, 160, $background);

        //4.填充图标
        $src = imagecreatefrompng($photo);
        imagecopyresampled($img, $src, 250, 10, 0, 0, $width, $height, $width, $height);

        //4.填充文字
        imagettftext($img, 18, 0, 30, 92, $fontColor, $font, $title);
        imagettftext($img, 13, 0, 30, 120, $fontColorAlpha, $font, $description);

        //4.保存图像
//        $pngQuality = ($quality - 100) / 11.111111;
//        $pngQuality = round(abs($pngQuality));
//        imagepng($resource, $path, $pngQuality);
        imagepng($img, $savepath . $filename);

        //5.释放画布资源
        imagedestroy($img);

        return $path . $filename;
    }

    /**
     * Determines the MIME type of the specified file.
     * This method will first try to determine the MIME type based on
     * [finfo_open](https://secure.php.net/manual/en/function.finfo-open.php). If the `fileinfo` extension is not installed,
     * it will fall back to [[getMimeTypeByExtension()]] when `$checkExtension` is true.
     * @param string $file the file name.
     * @param string $magicFile name of the optional magic database file (or alias), usually something like `/path/to/magic.mime`.
     * This will be passed as the second parameter to [finfo_open()](https://secure.php.net/manual/en/function.finfo-open.php)
     * when the `fileinfo` extension is installed. If the MIME type is being determined based via [[getMimeTypeByExtension()]]
     * and this is null, it will use the file specified by [[mimeMagicFile]].
     * @param bool $checkExtension whether to use the file extension to determine the MIME type in case
     * `finfo_open()` cannot determine it.
     * @return string|null the MIME type (e.g. `text/plain`). Null is returned if the MIME type cannot be determined.
     * @throws InvalidConfigException when the `fileinfo` PHP extension is not installed and `$checkExtension` is `false`.
     */
    public static function getMimeType($file, $magicFile = null, $checkExtension = true) {
        if ($magicFile !== null) {
            $magicFile = Yii::getAlias($magicFile);
        }
        if (!extension_loaded('fileinfo')) {
            if ($checkExtension) {
                return static::getMimeTypeByExtension($file, $magicFile);
            }
            throw new InvalidConfigException('The fileinfo PHP extension is not installed.');
        }
        $info = finfo_open(FILEINFO_MIME_TYPE, $magicFile);
        if ($info) {
            $result = finfo_file($info, $file);
            finfo_close($info);
            if ($result !== false) {
                return static::getOfficeMineType($result, $file, null, $magicFile);
            }
        }
        return $checkExtension ? static::getMimeTypeByExtension($file, $magicFile) : null;
    }

    /**
     * Determines the MIME type of the specified file.
     * This method will first try to determine the MIME type based on
     * [finfo_open](https://secure.php.net/manual/en/function.finfo-open.php). If the `fileinfo` extension is not installed,
     * it will fall back to [[getMimeTypeByExtension()]] when `$checkExtension` is true.
     * @param string $mineType the MIME type.
     * @param string|null $file the file name.
     * @param string|null $extension the MIME type.
     * `finfo_open()` cannot determine it.
     * @param string $magicFile name of the optional magic database file (or alias), usually something like `/path/to/magic.mime`.
     * This will be passed as the second parameter to [finfo_open()](https://secure.php.net/manual/en/function.finfo-open.php)
     * when the `fileinfo` extension is installed. If the MIME type is being determined based via [[getMimeTypeByExtension()]]
     * and this is null, it will use the file specified by [[mimeMagicFile]].
     * @return string|null the MIME type (e.g. `text/plain`). Null is returned if the MIME type cannot be determined.
     * @throws InvalidConfigException when the `fileinfo` PHP extension is not installed and `$checkExtension` is `false`.
     */
    public static function getOfficeMineType($mineType, $file = null, $extension = null, $magicFile = null) {
        if ($file === null && $extension === null) {
            return $mineType;
        }
        if (!in_array($mineType, ['application/octet-stream', 'application/zip', 'application/x-zip', 'application/x-zip-compressed'], true)) {
            return $mineType;
        }
        if (!$extension) {
            $extension = strtolower(pathinfo($file, PATHINFO_EXTENSION));
        }
        if ($extension && in_array($extension, ['pptx', 'docx', 'dotx', 'xlsx'], true)) {
            return static::getMimeTypeByExtension($file, $magicFile);
        }
        return $mineType;
    }

    /**
     * Determines the MIME type of the specified file.
     * This method will first try to determine the MIME type based on
     * [finfo_open](https://secure.php.net/manual/en/function.finfo-open.php). If the `fileinfo` extension is not installed,
     * it will fall back to [[getMimeTypeByExtension()]] when `$checkExtension` is true.
     * @param string $mineType the MIME type.
     * @param string|null $file the file name.
     * when the `fileinfo` extension is installed. If the MIME type is being determined based via [[getMimeTypeByExtension()]]
     * and this is null, it will use the file specified by [[mimeMagicFile]].
     * @return string|null the MIME type (e.g. `text/plain`). Null is returned if the MIME type cannot be determined.
     * @throws InvalidConfigException when the `fileinfo` PHP extension is not installed and `$checkExtension` is `false`.
     */
    public function getFileExtension($file) {
        $ext = pathinfo($file, PATHINFO_EXTENSION);
        if ($ext !== '') {
            $ext = strtolower($ext);
        }
        return $ext;
    }

}
